/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;

namespace FaceCat
{
    /// <summary>
    /// 公共类库
    /// </summary>
    public class FCNative
    {
        /// <summary>
        /// 创建公共类库
        /// </summary>
        public FCNative()
        {
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~FCNative()
        {
            delete();
        }

        /// <summary>
        /// 控件
        /// </summary>
        private ArrayList<FCView> m_views = new ArrayList<FCView>();

        /// <summary>
        /// 拖动开始时的触摸位置
        /// </summary>
        private FCPoint m_dragBeginPoint;

        /// <summary>
        /// 拖动开始时的区域
        /// </summary>
        private FCRect m_dragBeginRect;

        /// <summary>
        /// 可以开始拖动的偏移坐标量
        /// </summary>
        private FCPoint m_dragStartOffset;

        /// <summary>
        /// 正被拖动的控件
        /// </summary>
        private FCView m_draggingView;

        /// <summary>
        /// 即将导出的控件
        /// </summary>
        private FCView m_exportingView;

        /// <summary>
        /// 是否锁定更新
        /// </summary>
        public bool m_lockUpdate;

        /// <summary>
        /// 秒表集合
        /// </summary>
        private HashMap<int, FCView> m_timers = new HashMap<int, FCView>();

        /// <summary>
        /// 正被触摸按下的控件
        /// </summary>
        public FCView m_touchDownView;

        /// <summary>
        /// 触摸按下时的坐标
        /// </summary>
        private FCPoint m_touchDownPoint;

        /// <summary>
        /// 触摸正在其上方移动的控件
        /// </summary>
        public FCView m_touchMoveView;

        private bool m_allowScaleSize = false;

        /// <summary>
        /// 获取是否允许使用缩放尺寸
        /// </summary>
        public virtual bool allowScaleSize()
        {
            return m_allowScaleSize;
        }

        /// <summary>
        /// 设置是否允许使用缩放尺寸
        /// </summary>
        public virtual void setAllowScaleSize(bool value)
        {
            m_allowScaleSize = value;
        }

        /// <summary>
        /// 获取触摸形状
        /// </summary>
        public virtual FCCursors getCursor()
        {
            if (m_host != null)
            {
                return m_host.getCursor();
            }
            return FCCursors.Arrow;
        }

        /// <summary>
        /// 设置触摸形状
        /// </summary>
        public virtual void setCursor(FCCursors value)
        {
            m_host.setCursor(value);
        }

        private FCSize m_size;

        /// <summary>
        /// 获取显示区域
        /// </summary>
        public virtual FCSize getSize()
        {
            return m_size;
        }

        /// <summary>
        /// 设置显示区域
        /// </summary>
        public virtual void setSize(FCSize value)
        {
            m_size = value;
        }

        public FCView m_focusedView;

        /// <summary>
        /// 获取选中的控件
        /// </summary>
        public virtual FCView getFocusedView()
        {
            return m_focusedView;
        }

        /// <summary>
        /// 设置选中的控件
        /// </summary>
        public virtual void setFocusedView(FCView value)
        {
            if (m_focusedView != value)
            {
                if (m_focusedView != null)
                {
                    FCView fView = m_focusedView;
                    m_focusedView = null;
                    fView.onLostFocus();
                }
                m_focusedView = value;
                if (m_focusedView != null)
                {
                    m_focusedView.onGotFocus();
                }
            }
        }

        private FCHost m_host;

        /// <summary>
        /// 获取设备管理器
        /// </summary>
        public virtual FCHost getHost()
        {
            return m_host;
        }

        /// <summary>
        /// 设置设备管理器
        /// </summary>
        public virtual void setHost(FCHost value)
        {
            m_host = value;
        }

        /// <summary>
        /// 获取触摸悬停的控件
        /// </summary>
        public virtual FCView getHoveredView()
        {
            return m_touchMoveView;
        }

        private bool m_isDeleted;

        /// <summary>
        /// 获取或设置是否已被销毁
        /// </summary>
        public virtual bool isDeleted()
        {
            return m_isDeleted;
        }

        private float m_opacity = 1;

        /// <summary>
        /// 获取或设置透明度
        /// </summary>
        public virtual float getOpacity()
        {
            return m_opacity;
        }

        /// <summary>
        /// 设置透明度
        /// </summary>
        public virtual void setOpacity(float value)
        {
            m_opacity = value;
        }

        private FCPaint m_paint;

        /// <summary>
        /// 获取绘图类
        /// </summary>
        public virtual FCPaint getPaint()
        {
            return m_paint;
        }

        /// <summary>
        /// 设置绘图类
        /// </summary>
        public virtual void setPaint(FCPaint value)
        {
            m_paint = value;
        }

        /// <summary>
        /// 获取触摸按住的控件
        /// </summary>
        public virtual FCView getPushedView()
        {
            return m_touchDownView;
        }

        private String m_resourcePath;


        /// <summary>
        /// 获取资源文件的路径
        /// </summary>
        public virtual String getResourcePath()
        {
            return m_resourcePath;
        }

        /// <summary>
        /// 设置资源文件的路径
        /// </summary>
        public virtual void setResourcePath(String value)
        {
            m_resourcePath = value;
        }

        private int m_rotateAngle;

        /// <summary>
        /// 获取旋转角度
        /// </summary>
        public virtual int getRotateAngle()
        {
            return m_rotateAngle;
        }

        /// <summary>
        /// 设置旋转角度
        /// </summary>
        public virtual void setRotateAngle(int value)
        {
            m_rotateAngle = value;
        }

        private FCSize m_scaleSize;

        /// <summary>
        /// 获取使用缩放尺寸
        /// </summary>
        public virtual FCSize getScaleSize()
        {
            return m_scaleSize;
        }

        /// <summary>
        /// 设置使用缩放尺寸
        /// </summary>
        public virtual void setScaleSize(FCSize value)
        {
            m_scaleSize = value;
        }

        /// <summary>
        /// 获取触摸的实际位置
        /// </summary>
        public virtual FCPoint getTouchPoint()
        {
            if (m_host != null)
            {
                return m_host.getTouchPoint();
            }
            return new FCPoint(0, 0);
        }

        /// <summary>
        /// 添加控件
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void addView(FCView view)
        {
            view.setNative(this);
            m_views.add(view);
            view.onAdd();
        }

        /// <summary>
        /// 将控件放到最前显示
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void bringToFront(FCView view)
        {
            FCView parent = view.getParent();
            if (parent != null)
            {
                parent.bringChildToFront(view);
            }
            else
            {
                if (m_views != null && m_views.size() > 0)
                {
                    m_views.remove(view);
                    m_views.add(view);
                }
            }
        }

        /// <summary>
        /// 退出拖动
        /// </summary>
        public virtual void cancelDragging()
        {
            if (m_draggingView != null)
            {
                m_draggingView.setBounds(m_dragBeginRect);
                FCView draggingView = m_draggingView;
                m_draggingView = null;
                draggingView.onDragEnd();
                FCView parent = draggingView.getParent();
                if (parent != null)
                {
                    parent.invalidate();
                }
                else
                {
                    invalidate();
                }
            }
        }

        /// <summary>
        /// 清除所有的视图
        /// </summary>
        public virtual void clearViews()
        {
            while (m_views.size() > 0)
            {
                FCView view = m_views.get(0);
                m_views.removeAt(0);
                view.onRemove();
                view.delete();
            }
            m_touchDownView = null;
            m_touchMoveView = null;
        }

        /// <summary>
        /// 清除视图的状态
        /// </summary>
        public virtual void clearViewState(FCView view)
        {
            if (view == m_draggingView)
            {
                m_draggingView = null;
            }
            if (view == m_focusedView)
            {
                m_focusedView = null;
            }
            if (view == m_touchDownView)
            {
                m_touchDownView = null;
            }
            if (view == m_touchMoveView)
            {
                m_touchMoveView = null;
            }
            ArrayList<int> removeTimers = new ArrayList<int>();
            foreach (int timerID in m_timers.Keys)
            {
                if (m_timers.get(timerID) == view)
                {
                    removeTimers.add(timerID);
                }
            }
            foreach (int timerID in removeTimers)
            {
                stopTimer(timerID);
            }
            for (int i = 0; i < view.m_views.size(); i++)
            {
                clearViewState(view.m_views.get(i));
            }
        }

        /// <summary>
        /// 获取控件的绝对横坐标
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>坐标</returns>
        public virtual int clientX(FCView view)
        {
            if (view != null)
            {
                FCView parent = view.getParent();
                int cLeft = view.getLeft();
                if (view == m_exportingView)
                {
                    cLeft = 0;
                    return cLeft;
                }
                if (parent != null)
                {
                    return cLeft - (view.displayOffset() ? parent.getDisplayOffset().x : 0) + clientX(parent);
                }
                else
                {
                    return cLeft;
                }
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 获取控件的绝对纵坐标
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>坐标</returns>
        public virtual int clientY(FCView view)
        {
            if (view != null)
            {
                FCView parent = view.getParent();
                int cTop = view.getTop();
                if (view == m_exportingView)
                {
                    cTop = 0;
                    return cTop;
                }
                if (parent != null)
                {
                    return cTop - (view.displayOffset() ? parent.getDisplayOffset().y : 0) + clientY(parent);
                }
                else
                {
                    return cTop;
                }
            }
            else
            {
                return 0;
            }
        }

        public virtual FCPoint clientPoint(FCView view)
        {
            if (view != null)
            {
                FCView parent = view.getParent();
                int cLeft = view.getLeft();
                int cTop = view.getTop();
                if (view == m_exportingView)
                {
                    cTop = 0;
                    cLeft = 0;
                    return new FCPoint(cLeft, cTop);
                }
                if (parent != null)
                {
                    FCPoint parentClientY = clientPoint(parent);
                    if (view.displayOffset())
                    {
                        FCPoint displayOffset = parent.getDisplayOffset();
                        return new FCPoint(cLeft - displayOffset.x + parentClientY.x,
                       cTop - displayOffset.y + parentClientY.y);
                    }
                    else
                    {
                        return new FCPoint(cLeft + parentClientY.x,
                        cTop + parentClientY.y);
                    }
                }
                else
                {
                    return new FCPoint(cLeft, cTop);
                }
            }
            else
            {
                return new FCPoint(0, 0);
            }
        }

        /// <summary>
        /// 是否包含控件
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>是否包含</returns>
        public virtual bool containsView(FCView view)
        {
            foreach (FCView subView in m_views)
            {
                if (subView == view)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 销毁资源
        /// </summary>
        public virtual void delete()
        {
            if (!m_isDeleted)
            {
                m_timers.clear();
                clearViews();
                if (m_host != null)
                {
                    m_host.delete();
                }
                if (m_paint != null)
                {
                    m_paint.delete();
                }
                m_isDeleted = true;
            }
        }

        /// <summary>
        /// 导出到图片
        /// </summary>
        /// <param name="exportPath">导出路径</param>
        public virtual void exportToImage(String exportPath)
        {
            exportToImage(exportPath, null);
        }

        /// <summary>
        /// 导出控件到图片
        /// </summary>
        /// <param name="exportPath">导出路径</param>
        /// <param name="view">控件</param>
        public virtual void exportToImage(String exportPath, FCView view)
        {
            m_exportingView = view;
            if (view != null)
            {
                ArrayList<FCView> views = new ArrayList<FCView>();
                views.add(view);
                FCRect rect = new FCRect(0, 0, view.getWidth(), view.getHeight());
                m_paint.beginExport(exportPath, rect);
                renderViews(rect, views, getPaintingOpacity(view));
                m_paint.endExport();
            }
            else
            {
                FCRect rect = new FCRect(0, 0, m_size.cx, m_size.cy);
                m_paint.beginExport(exportPath, rect);
                ArrayList<FCView> subViews = new ArrayList<FCView>();
                getSortedViews(null, subViews);
                renderViews(rect, subViews, m_opacity);
                subViews.clear();
                m_paint.endExport();
            }
            m_exportingView = null;
        }

        /// <summary>
        /// 根据触摸位置获取控件
        /// </summary>
        /// <param name="mp">坐标</param>
        /// <param name="views">控件集合</param>
        /// <returns>控件对象</returns>
        public FCView findView(FCPoint mp, ArrayList<FCView> views)
        {
            int size = views.size();
            for (int i = size - 1; i >= 0; i--)
            {
                FCView view = views.get(i);
                if (view.isVisible())
                {
                    bool hasPoint = view.containsPoint(mp);
                    if (hasPoint)
                    {
                        ArrayList<FCView> subViews = new ArrayList<FCView>();
                        getSortedViews(view, subViews);
                        FCView subView = findView(mp, subViews);
                        subViews.clear();
                        if (subView != null)
                        {
                            return subView;
                        }
                        return view;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 根据名称查找控件
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="views">控件集合</param>
        /// <returns>控件</returns>
        private FCView findView(String name, ArrayList<FCView> views)
        {
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                if (view.getName() == name)
                {
                    return view;
                }
                else
                {
                    ArrayList<FCView> subViews = view.getViews();
                    if (subViews != null && subViews.size() > 0)
                    {
                        FCView fView = findView(name, subViews);
                        if (fView != null)
                        {
                            return fView;
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 根据坐标查找控件
        /// </summary>
        /// <param name="mp">坐标</param>
        /// <returns>控件</returns>
        public virtual FCView findView(FCPoint mp)
        {
            ArrayList<FCView> subViews = new ArrayList<FCView>();
            getSortedViews(null, subViews);
            FCView view = findView(mp, subViews);
            subViews.clear();
            return view;
        }

        /// <summary>
        /// 根据坐标在控件中查找控件
        /// </summary>
        /// <param name="mp">坐标</param>
        /// <param name="parent">父控件</param>
        /// <returns>控件</returns>
        public virtual FCView findView(FCPoint mp, FCView parent)
        {
            ArrayList<FCView> subViews = new ArrayList<FCView>();
            getSortedViews(parent, subViews);
            FCView view = findView(mp, subViews);
            subViews.clear();
            return view;
        }

        /// <summary>
        /// 根据名称查找控件
        /// </summary>
        /// <param name="name">名称</param>
        /// <returns>控件</returns>
        public virtual FCView findView(String name)
        {
            return findView(name, m_views);
        }

        /// <summary>
        /// 根据控件查找预处理事件的控件
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>控件</returns>
        public FCView findPreviewsView(FCView view)
        {
            if (view.allowPreviewsEvent())
            {
                return view;
            }
            else
            {
                FCView parent = view.getParent();
                if (parent != null)
                {
                    return findPreviewsView(parent);
                }
                else
                {
                    return view;
                }
            }
        }

        /// <summary>
        /// 根据控件查找窗体
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>窗体</returns>
        public FCView findWindow(FCView view)
        {
            if (view.isWindow())
            {
                return view;
            }
            else
            {
                FCView parent = view.getParent();
                if (parent != null)
                {
                    return findWindow(parent);
                }
                else
                {
                    return view;
                }
            }
        }

        /// <summary>
        /// 获取控件集合的拷贝
        /// </summary>
        /// <returns>控件集合</returns>
        public virtual ArrayList<FCView> getViews()
        {
            return m_views;
        }

        /// <summary>
        /// 获取焦点控件
        /// </summary>
        /// <param name="views">控件集合</param>
        /// <returns>焦点控件</returns>
        public FCView getFocusedView(ArrayList<FCView> views)
        {
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                if (view.isFocused())
                {
                    return view;
                }
                else
                {
                    //查找子控件
                    ArrayList<FCView> subViews = view.getViews();
                    if (subViews != null && subViews.size() > 0)
                    {
                        FCView focusedView = getFocusedView(subViews);
                        if (focusedView != null)
                        {
                            return focusedView;
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 获取绘制的透明度
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>透明度</returns>
        public float getPaintingOpacity(FCView view)
        {
            float opacity = view.getOpacity();
            FCView parent = view.getParent();
            if (parent != null)
            {
                opacity *= getPaintingOpacity(parent);
            }
            else
            {
                opacity *= m_opacity;
            }
            return opacity;
        }

        /// <summary>
        /// 获取排序后的控件集合
        /// </summary>
        /// <param name="parent">父控件</param>
        /// <param name="sortedViews">排序后的控件</param>
        /// <returns>状态</returns>
        public bool getSortedViews(FCView parent, ArrayList<FCView> sortedViews)
        {
            ArrayList<FCView> views = null;
            if (parent != null)
            {
                views = parent.getViews();
            }
            else
            {
                views = m_views;
            }
            int viewSize = views.size();
            int index = 0;
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                if (view.isVisible())
                {
                    if (view.isTopMost())
                    {
                        sortedViews.add(view);
                    }
                    else
                    {
                        sortedViews.Insert(index, view);
                        index++;
                    }
                }
            }
            return sortedViews.size() > 0;
        }

        /// <summary>
        /// 获取isTabStop()属性为TRUE的控件
        /// </summary>
        /// <param name="view"></param>
        public void getTabStopViews(FCView view, ArrayList<FCView> tabStopViews)
        {
            ArrayList<FCView> views = view.getViews();
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView subView = views.get(i);
                if (!subView.isWindow())
                {
                    if (subView.isEnabled() && subView.isTabStop())
                    {
                        tabStopViews.add(subView);
                    }
                    getTabStopViews(subView, tabStopViews);
                }
            }
        }

        /// <summary>
        /// 判断是否绘制可用状态
        /// </summary>
        /// <param name="view">控件</param>
        /// <returns>是否绘制可用状态</returns>
        public bool isPaintEnabled(FCView view)
        {
            if (view.isEnabled())
            {
                FCView parent = view.getParent();
                if (parent != null)
                {
                    return isPaintEnabled(parent);
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 插入控件
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="view">控件</param>
        public virtual void insertView(int index, FCView view)
        {
            view.setNative(this);
            m_views.Insert(index, view);
            view.onAdd();
        }

        /// <summary>
        /// 使用缓存绘制图象，不重新计算绘图结构
        /// </summary>
        public virtual void invalidate()
        {
            if (m_host != null)
            {
                m_host.invalidate();
            }
        }

        /// <summary>
        /// 局部绘图
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void invalidate(FCView view)
        {
            if (m_host != null)
            {
                int clX = clientX(view);
                int clY = clientY(view);
                m_host.invalidate(new FCRect(clX, clY, clX + view.getWidth(), clY + view.getHeight()));
            }
        }

        /// <summary>
        /// 局部绘图
        /// </summary>
        /// <param name="rect"> 区域</param>
        public virtual void invalidate(FCRect rect)
        {
            if (m_host != null)
            {
                m_host.invalidate(rect);
            }
        }

        /// <summary>
        /// 文字输入方法
        /// </summary>
        /// <param name="key">按键</param>
        /// <returns>是否处理</returns>
        public virtual bool onChar(char key)
        {
            FCView focusedView = getFocusedView();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                if (focusedView.isTabStop())
                {
                    FCView window = findWindow(focusedView);
                    if (window != null)
                    {
                        if (!(m_host.isKeyPress(0x10) || m_host.isKeyPress(0x11)) && key == 9)
                        {
                            ArrayList<FCView> tabStopViews = new ArrayList<FCView>();
                            getTabStopViews(window, tabStopViews);
                            int size = tabStopViews.size();
                            if (size > 0)
                            {
                                //排序
                                for (int i = 0; i < size - 1; i++)
                                {
                                    for (int j = 0; j < size - 1 - i; j++)
                                    {
                                        FCView viewLeft = tabStopViews.get(j);
                                        FCView viewRight = tabStopViews.get(j + 1);
                                        if (viewLeft.getTabIndex() > viewRight.getTabIndex())
                                        {
                                            FCView temp = tabStopViews.get(j + 1);
                                            tabStopViews.set(j + 1, tabStopViews.get(j));
                                            tabStopViews.set(j, temp);
                                        }
                                    }
                                }
                                //找到下一个控件
                                bool change = false;
                                FCView newFocusedView = null;
                                for (int i = 0; i < size; i++)
                                {
                                    FCView view = tabStopViews.get(i);
                                    if (focusedView == view)
                                    {
                                        if (i < size - 1)
                                        {
                                            newFocusedView = tabStopViews.get(i + 1);
                                        }
                                        else
                                        {
                                            newFocusedView = tabStopViews.get(0);
                                        }
                                        change = true;
                                        break;
                                    }
                                }
                                if (!change)
                                {
                                    newFocusedView = tabStopViews.get(0);
                                }
                                //转移焦点
                                if (newFocusedView != focusedView)
                                {
                                    newFocusedView.setFocused(true);
                                    focusedView = newFocusedView;
                                    focusedView.onTabStop();
                                    window.invalidate();
                                    return true;
                                }
                            }
                        }
                    }
                }
                focusedView.onChar(key);
            }
            return false;
        }

        /// <summary>
        /// 处理双击
        /// </summary>
        /// <param name="button">按钮</param>
        /// <param name="clicks">点击次数</param>
        /// <param name="delta">滚轮值</param>
        public virtual void onDoubleClick(FCTouchInfo touchInfo)
        {
            FCView focusedView = getFocusedView();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                FCPoint mp = getTouchPoint();
                int clx = clientX(focusedView);
                int cly = clientY(focusedView);
                FCPoint cmp = new FCPoint(mp.x - clx, mp.y - cly);
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = cmp;
                newTouchInfo.m_secondPoint = cmp;
                focusedView.onDoubleClick(newTouchInfo);
            }
        }

        /// <summary>
        /// 处理键盘按下
        /// </summary>
        /// <param name="key">按键</param>
        public virtual void onKeyDown(char key)
        {
            FCView focusedView = getFocusedView();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                focusedView.onKeyDown(key);
            }
        }

        /// <summary>
        /// 处理键盘抬起
        /// </summary>
        /// <param name="key">按键</param>
        public virtual void onKeyUp(char key)
        {
            FCView focusedView = getFocusedView();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                focusedView.onKeyUp(key);
            }
        }

        /// <summary>
        /// 触摸单击事件
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onMouseDown(FCTouchInfo touchInfo)
        {
            m_draggingView = null;
            m_touchDownView = null;
            FCPoint mp = getTouchPoint();
            m_touchDownPoint = mp;
            ArrayList<FCView> subViews = new ArrayList<FCView>();
            getSortedViews(null, subViews);
            FCView view = findView(mp, subViews);
            subViews.clear();
            if (view != null)
            {
                //将窗体置顶
                FCView window = findWindow(view);
                if (window != null && window.isWindow())
                {
                    window.bringToFront();
                }
                if (isPaintEnabled(view))
                {
                    int clx = clientX(view);
                    int cly = clientY(view);
                    FCPoint cmp = new FCPoint(mp.x - clx, mp.y - cly);
                    FCView focusedView = getFocusedView();
                    //触发事件
                    m_touchDownView = view;
                    if (focusedView == getFocusedView())
                    {
                        if (view.canFocus())
                        {
                            //选中控件
                            setFocusedView(view);
                        }
                    }
                    if (onPreviewsTouchEvent("ontouchdown", m_touchDownView, touchInfo))
                    {
                        m_touchDownView = null;
                        return;
                    }
                    FCTouchInfo newTouchInfo = touchInfo.clone();
                    newTouchInfo.m_firstPoint = cmp;
                    newTouchInfo.m_secondPoint = cmp;
                    if (m_touchDownView != null)
                    {
                        m_touchDownView.onTouchDown(newTouchInfo);
                    }
                    if (m_touchDownView != null)
                    {
                        m_touchDownView.onDragReady(ref m_dragStartOffset);
                    }
                }
            }
        }

        /// <summary>
        /// 触摸离开事件
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onMouseLeave(FCTouchInfo touchInfo)
        {
            //调用触摸离开事件
            if (m_touchMoveView != null && isPaintEnabled(m_touchMoveView))
            {
                FCPoint mp = getTouchPoint();
                FCPoint cmp = new FCPoint(mp.x - clientX(m_touchMoveView), mp.y - clientY(m_touchMoveView));
                FCView touchMoveView = m_touchMoveView;
                m_touchMoveView = null;
                if (onPreviewsTouchEvent("ontouchleave", m_touchDownView, touchInfo))
                {
                    return;
                }
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = cmp;
                newTouchInfo.m_secondPoint = cmp;
                touchMoveView.onTouchLeave(newTouchInfo);
            }
        }

        /// <summary>
        /// 触摸移动事件
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onMouseMove(FCTouchInfo touchInfo)
        {
            FCPoint mp = getTouchPoint();
            //按下控件时
            if (m_touchDownView != null)
            {
                if (onPreviewsTouchEvent("ontouchmove", m_touchDownView, touchInfo))
                {
                    return;
                }
                FCPoint cmp = new FCPoint(mp.x - clientX(m_touchDownView), mp.y - clientY(m_touchDownView));
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = cmp;
                newTouchInfo.m_secondPoint = cmp;
                m_touchDownView.onTouchMove(newTouchInfo);
                setCursor(m_touchDownView);
                //拖动
                if (m_touchDownView.allowDrag() && newTouchInfo.m_firstTouch && newTouchInfo.m_clicks == 1)
                {
                    if (Math.Abs(mp.x - m_touchDownPoint.x) > m_dragStartOffset.x
                        || Math.Abs(mp.y - m_touchDownPoint.y) > m_dragStartOffset.y)
                    {
                        //触发事件
                        if (m_touchDownView.onDragBegin())
                        {
                            m_dragBeginRect = m_touchDownView.getBounds();
                            m_dragBeginPoint = m_touchDownPoint;
                            m_draggingView = m_touchDownView;
                            m_touchDownView = null;
                            FCView parent = m_draggingView.getParent();
                            if (parent != null)
                            {
                                parent.invalidate();
                            }
                            else
                            {
                                invalidate();
                            }
                        }
                    }
                }
            }
            //拖动时
            else if (m_draggingView != null)
            {
                FCView draggingView = m_draggingView;
                int offsetX = mp.x - m_dragBeginPoint.x;
                int offsetY = mp.y - m_dragBeginPoint.y;
                FCRect newBounds = m_dragBeginRect;
                newBounds.left += offsetX;
                newBounds.top += offsetY;
                newBounds.right += offsetX;
                newBounds.bottom += offsetY;
                draggingView.setBounds(newBounds);
                //触发正在拖动事件
                draggingView.onDragging();
                FCView parent = draggingView.getParent();
                if (parent != null)
                {
                    parent.invalidate();
                }
                else
                {
                    invalidate();
                }
            }
            else
            {
                ArrayList<FCView> subViews = new ArrayList<FCView>();
                getSortedViews(null, subViews);
                FCView view = findView(mp, subViews);
                if (view != null)
                {
                    if (onPreviewsTouchEvent("ontouchmove", view, touchInfo))
                    {
                        return;
                    }
                }
                subViews.clear();
                if (m_touchMoveView != view)
                {
                    //调用触摸离开事件
                    if (m_touchMoveView != null && isPaintEnabled(m_touchMoveView))
                    {
                        if (m_touchDownView == null)
                        {
                            FCPoint cmp = new FCPoint(mp.x - clientX(m_touchMoveView), mp.y - clientY(m_touchMoveView));
                            FCView touchMoveView = m_touchMoveView;
                            m_touchMoveView = view;
                            FCTouchInfo newTouchInfo = touchInfo.clone();
                            newTouchInfo.m_firstPoint = cmp;
                            newTouchInfo.m_secondPoint = cmp;
                            touchMoveView.onTouchLeave(newTouchInfo);
                        }
                    }
                    if (view != null && isPaintEnabled(view))
                    {
                        if (m_touchDownView == null)
                        {
                            FCPoint cmp = new FCPoint(mp.x - clientX(view), mp.y - clientY(view));
                            m_touchMoveView = view;
                            //调用触摸进入事件
                            FCTouchInfo newTouchInfo = touchInfo.clone();
                            newTouchInfo.m_firstPoint = cmp;
                            newTouchInfo.m_secondPoint = cmp;
                            view.onTouchEnter(newTouchInfo);
                            view.onTouchMove(newTouchInfo);
                            setCursor(view);
                        }
                    }
                }
                else
                {
                    //调用触摸移动事件
                    if (view != null && isPaintEnabled(view))
                    {
                        FCPoint cmp = new FCPoint(mp.x - clientX(view), mp.y - clientY(view));
                        m_touchMoveView = view;
                        FCTouchInfo newTouchInfo = touchInfo.clone();
                        newTouchInfo.m_firstPoint = cmp;
                        newTouchInfo.m_secondPoint = cmp;
                        view.onTouchMove(newTouchInfo);
                        setCursor(view);
                    }
                }
            }
        }

        /// <summary>
        /// 触摸弹起事件
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onMouseUp(FCTouchInfo touchInfo)
        {
            FCPoint mp = getTouchPoint();
            ArrayList<FCView> subViews = new ArrayList<FCView>();
            getSortedViews(null, subViews);
            //获取触摸按下的控件
            if (m_touchDownView != null)
            {
                FCView touchDownView = m_touchDownView;
                if (onPreviewsTouchEvent("ontouchup", touchDownView, touchInfo))
                {
                    m_touchDownView = null;
                    return;
                }
                if (m_touchDownView != null)
                {
                    FCView view = findView(mp, subViews);
                    FCPoint cmp = new FCPoint(mp.x - clientX(m_touchDownView), mp.y - clientY(m_touchDownView));
                    if (view != null && view == m_touchDownView)
                    {
                        FCTouchInfo newTouchInfo = touchInfo.clone();
                        newTouchInfo.m_firstPoint = cmp;
                        newTouchInfo.m_secondPoint = cmp;
                        m_touchDownView.onClick(newTouchInfo);
                    }
                    else
                    {
                        m_touchMoveView = null;
                    }
                    //触发单击和双击事件
                    if (m_touchDownView != null)
                    {
                        touchDownView = m_touchDownView;
                        m_touchDownView = null;
                        FCTouchInfo newTouchInfo = touchInfo.clone();
                        newTouchInfo.m_firstPoint = cmp;
                        newTouchInfo.m_secondPoint = cmp;
                        touchDownView.onTouchUp(newTouchInfo);
                    }
                }
            }
            else if (m_draggingView != null)
            {
                FCPoint cmp = new FCPoint(mp.x - clientX(m_touchDownView), mp.y - clientY(m_touchDownView));
                FCView draggingView = m_draggingView;
                m_draggingView = null;
                if (onPreviewsTouchEvent("ontouchup", draggingView, touchInfo))
                {
                    return;
                }
                //触发单击和双击事件
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = cmp;
                newTouchInfo.m_secondPoint = cmp;
                draggingView.onTouchUp(newTouchInfo);
                //触发拖动结束事件
                draggingView.onDragEnd();
                FCView parent = draggingView.getParent();
                if (parent != null)
                {
                    parent.invalidate();
                }
                else
                {
                    invalidate();
                }
            }
            subViews.clear();
        }

        /// <summary>
        /// 触摸滚动事件
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public virtual void onMouseWheel(FCTouchInfo touchInfo)
        {
            FCPoint mp = getTouchPoint();
            ArrayList<FCView> subViews = new ArrayList<FCView>();
            getSortedViews(null, subViews);
            FCView focusedView = findView(mp, subViews);
            subViews.clear();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                if (onPreviewsTouchEvent("ontouchwheel", focusedView, touchInfo))
                {
                    return;
                }
                mp.x -= clientX(focusedView);
                mp.y -= clientY(focusedView);
                touchInfo.m_firstPoint = mp;
                touchInfo.m_secondPoint = mp;
                focusedView.onTouchWheel(touchInfo);
            }
        }

        /// <summary>
        /// 绘图方法
        /// </summary>
        /// <param name="clipRect">矩形区域</param>
        public virtual void onPaint(FCRect clipRect)
        {
            ArrayList<FCView> subControls = new ArrayList<FCView>();
            getSortedViews(null, subControls);
            renderViews(clipRect, subControls, m_opacity);
            subControls.clear();
        }

        /// <summary>
        /// 预处理键盘事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="key">按键</param>
        /// <returns>状态</returns>
        public virtual bool onPreviewsKeyEvent(String eventName, char key)
        {
            FCView focusedView = getFocusedView();
            if (focusedView != null && isPaintEnabled(focusedView))
            {
                FCView window = findWindow(focusedView);
                if (window != null)
                {
                    return window.onPreviewsKeyEvent(eventName, key);
                }
            }
            return false;
        }

        /// <summary>
        /// 预处理触摸事件
        /// </summary>
        /// <param name="eventName">事件ID</param>
        /// <param name="view">控件</param>
        /// <param name="touchInfo">触摸信息</param>
        /// <returns></returns>
        public virtual bool onPreviewsTouchEvent(String eventName, FCView view, FCTouchInfo touchInfo)
        {
            FCView previewsView = findPreviewsView(view);
            if (previewsView != null)
            {
                FCPoint mp = touchInfo.m_firstPoint;
                int clx = clientX(previewsView);
                int cly = clientY(previewsView);
                FCPoint wcmp = new FCPoint(mp.x - clx, mp.y - cly);
                FCTouchInfo newTouchInfo = touchInfo.clone();
                newTouchInfo.m_firstPoint = wcmp;
                newTouchInfo.m_secondPoint = wcmp;
                if (previewsView.onPreviewsTouchEvent(eventName, newTouchInfo))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 处理尺寸改变
        /// </summary>
        public virtual void onResize()
        {
            update();
        }

        /// <summary>
        /// 缩放
        /// </summary>
        public virtual void onScaling(double scaleFactorX, double scaleFactorY)
        {
            int viewSize = m_views.size();
            for (int i = 0; i < viewSize; i++)
            {
                m_views.get(i).onScaling(scaleFactorX, scaleFactorY);
            }
        }

        /// <summary>
        /// 处理秒表
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        public virtual void onTimer(int timerID)
        {
            if (m_timers.containsKey(timerID))
            {
                m_timers.get(timerID).onTimer(timerID);
            }
        }

        /// <summary>
        /// 绘制视图
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="resourcePath"></param>
        /// <param name="opacity"></param>
        public void renderView(FCRect rect, FCView view, float opacity)
        {
            FCRect destRect = new FCRect();
            FCPoint cPoint = clientPoint(view);
            int clx = cPoint.x;
            int cly = cPoint.y;
            FCRect bounds = new FCRect(clx, cly, clx + view.getWidth(), cly + view.getHeight());
            //获取自定义裁剪区域
            if (view.useRegion())
            {
                FCRect clipRect = view.getRegion();
                bounds.left += clipRect.left;
                bounds.top += clipRect.top;
                bounds.right = bounds.left + clipRect.right - clipRect.left;
                bounds.bottom = bounds.top + clipRect.bottom - clipRect.top;
            }
            if (view.isVisible() && m_host.getIntersectRect(ref destRect, ref rect, ref bounds) > 0)
            {
                //设置裁剪
                FCRect clipRect = new FCRect(destRect.left - clx, destRect.top - cly,
                    destRect.right - clx, destRect.bottom - cly);
                //设置透明度
                float newOpacity = view.getOpacity() * opacity;
                setPaint(clx, cly, clipRect, newOpacity);
                FCSize oldSize = view.getSize();
                bool flag = view.onPrePaint(m_paint, clipRect);
                FCSize newSize = view.getSize();
                if (oldSize.cx != newSize.cx || oldSize.cy != newSize.cy)
                {
                    bounds.left = clx;
                    bounds.top = cly;
                    bounds.right = clx + view.getWidth();
                    bounds.bottom = cly + view.getHeight();
                    if (view.useRegion())
                    {
                        FCRect clipRect2 = view.getRegion();
                        bounds.left += clipRect2.left;
                        bounds.top += clipRect2.top;
                        bounds.right = bounds.left + clipRect2.right - clipRect2.left;
                        bounds.bottom = bounds.top + clipRect2.bottom - clipRect2.top;
                    }
                    if (m_host.getIntersectRect(ref destRect, ref rect, ref bounds) > 0)
                    {
                        clipRect.left = destRect.left - clx;
                        clipRect.top = destRect.top - cly;
                        clipRect.right = destRect.right - clx;
                        clipRect.bottom = destRect.bottom - cly;
                        setPaint(clx, cly, clipRect, newOpacity);

                    }
                    else
                    {
                        flag = false;
                        return;
                    }
                }
                if (!flag)
                {
                    view.onPaint(m_paint, clipRect);
                }
                ArrayList<FCView> views = view.m_views;
                int viewSize = views.size();
                ArrayList<FCView> topViews = new ArrayList<FCView>();
                for (int i = 0; i < viewSize; i++)
                {
                    FCView subView = views.get(i);
                    if (subView.isVisible())
                    {
                        if (subView.isTopMost())
                        {
                            topViews.add(subView);
                            //sortedViews.add(view);
                        }
                        else
                        {
                            renderView(destRect, subView, newOpacity);
                        }
                    }
                }
                int topViewsSize = topViews.size();
                for (int i = 0; i < topViewsSize; i++)
                {
                    renderView(destRect, topViews.get(i), newOpacity);
                }
                topViews.clear();

                setPaint(clx, cly, clipRect, newOpacity);
                if (!flag)
                {
                    view.onPaintBorder(m_paint, clipRect);
                }
            }
        }

        /// <summary>
        /// 绘制控件
        /// </summary>
        /// <param name="rect">矩形</param>
        /// <param name="views">控件集合</param>
        /// <param name="resourcePath">资源路径</param>
        /// <param name="opacity">透明度</param>
        public void renderViews(FCRect rect, ArrayList<FCView> views, float opacity)
        {
            m_paint.setResourcePath(m_resourcePath);
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                renderView(rect, view, opacity);
            }
        }

        /// <summary>
        /// 移除控件
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void removeView(FCView view)
        {
            clearViewState(view);
            if (view.getParent() == null)
            {
                m_views.remove(view);
                view.onRemove();
            }
        }

        /// <summary>
        /// 将控件放到最下面显示
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void sendToBack(FCView view)
        {
            FCView parent = view.getParent();
            if (parent != null)
            {
                parent.sendChildToBack(view);
            }
            else
            {
                if (m_views != null && m_views.size() > 0)
                {
                    m_views.remove(view);
                    m_views.Insert(0, view);
                }
            }
        }

        /// <summary>
        /// 设置排列
        /// </summary>
        /// <param name="views">控件集合</param>
        public virtual void setAlign(ArrayList<FCView> views)
        {
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                if (view.displayOffset())
                {
                    if (view.getAlign() == FCHorizontalAlign.Left && view.getVerticalAlign() == FCVerticalAlign.Top)
                    {
                        continue;
                    }
                    FCSize parentSize = m_size;
                    FCView parent = view.getParent();
                    if (parent != null)
                    {
                        parentSize = parent.getSize();
                    }
                    FCSize size = view.getSize();
                    FCPadding margin = view.getMargin();
                    FCPadding padding = new FCPadding();
                    if (parent != null)
                    {
                        padding = parent.getPadding();
                    }
                    if (view.getAlign() == FCHorizontalAlign.Center)
                    {
                        view.setLeft((parentSize.cx - size.cx) / 2);
                    }
                    else if (view.getAlign() == FCHorizontalAlign.Right)
                    {
                        view.setLeft(parentSize.cx - size.cx - margin.right - padding.right);
                    }
                    if (view.getVerticalAlign() == FCVerticalAlign.Bottom)
                    {
                        view.setTop(parentSize.cy - size.cy - margin.bottom - padding.bottom);
                    }
                    else if (view.getVerticalAlign() == FCVerticalAlign.Middle)
                    {
                        view.setTop((parentSize.cy - size.cy) / 2);
                    }
                }
            }
        }

        /// <summary>
        /// 设置锚定信息
        /// </summary>
        /// <param name="views">控件集合</param>
        /// <param name="oldSize">原尺寸</param>
        public virtual void setAnchor(ArrayList<FCView> views, FCSize oldSize)
        {
            if (oldSize.cx != 0 && oldSize.cy != 0)
            {
                int viewSize = views.size();
                for (int i = 0; i < viewSize; i++)
                {
                    FCView view = views.get(i);
                    FCAnchor anchor = view.getAnchor();
                    if (anchor.left && anchor.top && !anchor.right && !anchor.bottom)
                    {
                        continue;
                    }
                    FCSize parentSize = m_size;
                    FCView parent = view.getParent();
                    if (parent != null)
                    {
                        parentSize = parent.getSize();
                    }
                    FCRect bounds = view.getBounds();
                    if (anchor.right && !anchor.left)
                    {
                        bounds.left = bounds.left + parentSize.cx - oldSize.cx;
                    }
                    if (anchor.bottom && !anchor.top)
                    {
                        bounds.top = bounds.top + parentSize.cy - oldSize.cy;
                    }
                    if (anchor.right)
                    {
                        bounds.right = bounds.right + parentSize.cx - oldSize.cx;
                    }
                    if (anchor.bottom)
                    {
                        bounds.bottom = bounds.bottom + parentSize.cy - oldSize.cy;
                    }
                    view.setBounds(bounds);
                }
            }
        }

        /// <summary>
        /// 设置光标
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void setCursor(FCView view)
        {
            FCCursors cursor = view.getCursor();
            if (!isPaintEnabled(view))
            {
                cursor = FCCursors.Arrow;
            }
            if (this.getCursor() != cursor)
            {
                this.setCursor(cursor);
            }
        }

        /// <summary>
        /// 设置绑定边缘
        /// </summary>
        /// <param name="view">控件</param>
        public virtual void setDock(ArrayList<FCView> views)
        {
            int viewSize = views.size();
            for (int i = 0; i < viewSize; i++)
            {
                FCView view = views.get(i);
                FCDockStyle dock = view.getDock();
                if (dock != FCDockStyle.None)
                {
                    FCSize parentSize = m_size;
                    FCView parent = view.getParent();
                    if (parent != null)
                    {
                        parentSize = parent.getSize();
                    }
                    FCPadding padding = new FCPadding();
                    if (parent != null)
                    {
                        padding = parent.getPadding();
                    }
                    FCPadding margin = view.getMargin();
                    FCSize cSize = view.getSize();
                    FCRect spaceRect = new FCRect(padding.left + margin.left, padding.top + margin.top, parentSize.cx - padding.right - margin.right, parentSize.cy - padding.bottom - margin.bottom);
                    if (dock == FCDockStyle.Bottom)
                    {
                        FCRect bounds = new FCRect(spaceRect.left, spaceRect.bottom - cSize.cy, spaceRect.right, spaceRect.bottom);
                        view.setBounds(bounds);
                    }
                    else if (dock == FCDockStyle.Fill)
                    {
                        FCRect bounds = new FCRect(spaceRect.left, spaceRect.top, spaceRect.right, spaceRect.bottom);
                        view.setBounds(bounds);
                    }
                    else if (dock == FCDockStyle.Left)
                    {
                        FCRect bounds = new FCRect(spaceRect.left, spaceRect.top, spaceRect.left + cSize.cx, spaceRect.bottom);
                        view.setBounds(bounds);
                    }
                    else if (dock == FCDockStyle.Right)
                    {
                        FCRect bounds = new FCRect(spaceRect.right - cSize.cx, spaceRect.top, spaceRect.right, spaceRect.bottom);
                        view.setBounds(bounds);
                    }
                    else if (dock == FCDockStyle.Top)
                    {
                        FCRect bounds = new FCRect(spaceRect.left, spaceRect.top, spaceRect.right, spaceRect.top + cSize.cy);
                        view.setBounds(bounds);
                    }
                }
            }
        }

        /// <summary>
        /// 设置绘图属性
        /// </summary>
        /// <param name="offsetX">横向偏移</param>
        /// <param name="offsetY">纵向偏移</param>
        /// <param name="clipRect">裁剪区域</param>
        /// <param name="resourcePath">资源路径</param>
        /// <param name="opacity">透明度</param>
        private void setPaint(int offsetX, int offsetY, FCRect clipRect, float opacity)
        {
            m_paint.setOffset(new FCPoint(offsetX, offsetY));
            m_paint.setClip(clipRect);
            m_paint.setOpacity(opacity);
        }

        /// <summary>
        /// 启动秒表
        /// </summary>
        /// <param name="view">控件</param>
        /// <param name="timerID">秒表编号</param>
        /// <param name="interval">间隔</param>
        public virtual void startTimer(FCView view, int timerID, int interval)
        {
            m_timers.put(timerID, view);
            if (m_host != null)
            {
                m_host.startTimer(timerID, interval);
            }
        }

        /// <summary>
        /// 停止秒表
        /// </summary>
        /// <param name="timerID">秒表编号</param>
        public virtual void stopTimer(int timerID)
        {
            if (m_timers.containsKey(timerID))
            {
                if (m_host != null)
                {
                    m_host.stopTimer(timerID);
                }
                m_timers.remove(timerID);
            }
        }

        /// <summary>
        /// 更新布局
        /// </summary>
        public virtual void update()
        {
            if (m_host != null && !m_lockUpdate)
            {
                FCSize oldSize = m_size;
                m_size = m_host.getSize();
                if (m_size.cx != 0 && m_size.cy != 0)
                {
                    setAlign(m_views);
                    setAnchor(m_views, oldSize);
                    setDock(m_views);
                    int viewsSize = m_views.size();
                    for (int i = 0; i < viewsSize; i++)
                    {
                        m_views.get(i).update();
                    }
                }
            }
        }

        public static int m_changeID = 0;

        public static void addChangeID()
        {
            m_changeID++;
        }

        public static int getChangeID()
        {
            return m_changeID;
        }
    }
}
